home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / ippon / data / etc / lboss04.lzh / enemy.c < prev    next >
C/C++ Source or Header  |  1999-05-20  |  10KB  |  436 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <XSP2lib.H>
  5. #include "main.h"
  6. #include "enemy.h"
  7. #include "fxsp2lib.h"
  8. #include "parts.h"
  9.  
  10. #define SEQ_WING_ERASE    67
  11.  
  12. #define ENEMY_MAX    64    /* 最大数 */
  13.  
  14. static ENEMY enemy[ENEMY_MAX];    /* ワーク */
  15. static ENEMY *enemy_top,    /* 使用中のワークのリスト */
  16.  *enemy_null_top,        /* 空のワークのリスト */
  17.  *enemy_end;            /* 使用中ワークのリストの末尾 */
  18.  
  19.  
  20. extern char end_of_data;
  21. extern char f_option_flag;
  22.  
  23. typedef struct _spwork {
  24.     signed short x, y;    /* 座標 */
  25.     unsigned short pt;    /* スプライトパターンNo. */
  26.     unsigned short info;    /* 反転コード・色・優先度を表わすデータ */
  27. } SPWORK;
  28.  
  29.  
  30. SPWORK spwork;
  31.  
  32. static FILE *fp_parts5,*fp_parts6;
  33.  
  34.  
  35. int EnemyInit0 (void)
  36. {
  37.     int i;
  38.  
  39.     /* リストをつなげる */
  40.     enemy_top = NULL;
  41.     enemy_end = NULL;
  42.     enemy_null_top = enemy;
  43.     for (i = 0; i < ENEMY_MAX; i++)
  44.         enemy[i].next = &enemy[i + 1];
  45.  
  46.     enemy[ENEMY_MAX - 1].next = NULL;
  47.  
  48.     return(0);
  49. }
  50.  
  51.  
  52.  
  53. void EnemyInit (unsigned short type, unsigned short info,
  54.         signed short ox, signed short oy, ENEMY * parent)
  55. {
  56.     ENEMY *p;
  57.  
  58.     if (enemy_null_top == NULL) {
  59.         printf ("ワークが一杯です\n");
  60.         return;        /* 空きのワークがない(キャラクターオーバー) */
  61.     }
  62.     /* リストの末尾に新しいノードを追加 */
  63.     p = enemy_null_top;
  64.     enemy_null_top = p->next;
  65.     if (enemy_top == NULL)
  66.         enemy_top = p;
  67.     else
  68.         enemy_end->next = p;
  69.     p->next = NULL;
  70.     enemy_end = p;
  71.  
  72.     p->type = type;
  73.     p->info = info;
  74.     p->ox = ox;
  75.     p->oy = oy;
  76.     p->x = p->y = 0;
  77.     p->parent = parent;
  78.  
  79.     p->lx = p->ly = p->lz = 0.0;
  80.     p->vx = p->vy = p->vz = 0.0;
  81.     p->cyc = 0;
  82.     p->cyc1 = 0;
  83.     p->round = p->round_v = p->spring = p->spring_v = 0.0;
  84.  
  85.     switch (p->type) {
  86.     case 1:
  87.         EnemyInit (3, 0x0437, -16 - 8, 0, p);    /* 左翼(大) */
  88.         break;
  89.     case 2:
  90.         EnemyInit (4, 0x0437, 16 + 8, 0, p);    /* 右翼(大) */
  91.         break;
  92.     case 5:
  93.         if (f_option_flag)
  94.             fp_parts5 = fopen ("parts5.doc", "w");
  95.         break;
  96.     case 6:
  97.         if (f_option_flag)
  98.             fp_parts6 = fopen ("parts6.doc", "w");
  99.         break;
  100.     default:
  101.         break;
  102.     }
  103. }
  104.  
  105.  
  106. /* 複数のスプライトで構成されているパーツ1個分のスプライトをまとめて表示 */
  107. static void DispSp (ENEMY * p, short sp_num, PARTS_TABLE * parts_table)
  108. {
  109.     short h;
  110.  
  111.     for (h = 0; h < sp_num; h++) {
  112.         p->x = p->lx + p->ox;
  113.         p->y = p->ly + p->oy;
  114.         if (p->parent != NULL) {
  115.             spwork.x = p->x + p->parent->x + parts_table[h].x;
  116.             spwork.y = p->y + p->parent->y + parts_table[h].y;
  117.         } else {
  118.             spwork.x = p->x + parts_table[h].x;
  119.             spwork.y = p->y + parts_table[h].y;
  120.         }
  121.         spwork.pt = parts_table[h].pt;
  122.         spwork.info = p->info;
  123.  
  124.         spwork.x += (128 + 16);    /* 表示用に補正 */
  125.         spwork.y += (128 + 16);
  126.         xsp_set_st (&spwork);
  127.         fxsp_set_st (&spwork);
  128.         spwork.x -= (128 + 16);
  129.         spwork.y -= (128 + 16);
  130.     }
  131. }
  132.  
  133.  
  134.  
  135. void EnemyMove (void)
  136. {
  137.     ENEMY *p, *q;
  138.  
  139.     p = enemy_top;
  140.     q = NULL;
  141.     while (p != NULL) {
  142.         char erase_flag = 0;
  143.  
  144.         switch (p->type) {
  145.         case 0:    /* 本体 */
  146.             DispSp (p, 48, parts0_table);
  147.             break;
  148.  
  149.         case 1:    /* 左翼(小) */
  150.             switch (p->cyc) {
  151. #define R1    8        /* 半径 */
  152. #define RA1    (0.02)        /* 加速度 */
  153. #define RV1_MAX (0.3)        /* 速度最大値 */
  154.             case 0:/* 回転 */
  155.                 p->round += p->round_v;
  156.                 if ((p->round_v += RA1) > RV1_MAX)
  157.                     p->round_v = RV1_MAX;
  158.                 p->lx = R1 * cos (p->round);
  159.                 p->ly = R1 * sin (p->round);
  160. #define R1_MAX (M_PI)
  161.                 if (p->round > R1_MAX) {
  162.                     p->round -= R1_MAX;
  163.                     p->cyc++;
  164.                 }
  165.                 break;
  166.             case 1:/* ばね振動 */
  167. #define SPRING_K1    0.5
  168. #define SPRING_M1    0.8    /* 摩擦計数 */
  169. #define ROUND_MIN1    0.03    /* 座標がこれ以下になれば中断 */
  170. #define ROUNDV_MIN1    0.10    /* 速度がこれ以下になれば中断 */
  171.                 p->round += p->round_v;
  172.                 p->round_v -= SPRING_K1 * p->round;
  173.                 p->round_v *= SPRING_M1;
  174.                 if ((fabs (p->round) < ROUND_MIN1) && (fabs (p->round_v) < ROUNDV_MIN1))
  175.                     p->cyc++;
  176.                 p->lx = R1 * cos (R1_MAX + p->round);
  177.                 p->ly = R1 * sin (R1_MAX + p->round);
  178.                 break;
  179.             case 2:
  180.                 p->lx = R1 * cos (R1_MAX + p->round);
  181.                 p->ly = R1 * sin (R1_MAX + p->round);
  182.                 break;
  183.             default:
  184.                 break;
  185.             }
  186.             DispSp (p, 25, parts1_table);
  187.             if (seq_counter == SEQ_WING_ERASE)
  188.                 erase_flag = !0;
  189.             break;
  190.  
  191.         case 2:    /* 右翼(小) */
  192.             switch (p->cyc) {
  193.             case 0:/* 回転 */
  194.                 p->round += p->round_v;
  195.                 if ((p->round_v += RA1) > RV1_MAX)
  196.                     p->round_v = RV1_MAX;
  197.                 p->lx = -R1 * cos (p->round);
  198.                 p->ly = R1 * sin (p->round);
  199.                 if (p->round > R1_MAX) {
  200.                     p->round -= R1_MAX;
  201.                     p->cyc++;
  202.                 }
  203.                 break;
  204.             case 1:/* ばね振動 */
  205.                 p->round += p->round_v;
  206.                 p->round_v -= SPRING_K1 * p->round;
  207.                 p->round_v *= SPRING_M1;
  208.                 if ((fabs (p->round) < ROUND_MIN1) && (fabs (p->round_v) < ROUNDV_MIN1))
  209.                     p->cyc++;
  210.                 p->lx = -R1 * cos (R1_MAX + p->round);
  211.                 p->ly = R1 * sin (R1_MAX + p->round);
  212.                 break;
  213.             case 2:
  214.                 p->lx = -R1 * cos (R1_MAX + p->round);
  215.                 p->ly = R1 * sin (R1_MAX + p->round);
  216.                 break;
  217.             default:
  218.                 break;
  219.             }
  220.             DispSp (p, 25, parts2_table);
  221.             if (seq_counter == SEQ_WING_ERASE)
  222.                 erase_flag = !0;
  223.             break;
  224.  
  225.         case 3:    /* 左翼(大) */
  226.             switch (p->cyc) {
  227. #define R3    8        /* 半径 */
  228.             case 0:
  229.                 p->lx = R3 * cos (p->round);
  230.                 p->ly = R3 * sin (p->round);
  231.                 if (seq_counter == 25)
  232.                     p->cyc++;
  233.                 break;
  234. #define RA3    (0.02)        /* 加速度 */
  235. #define RV3_MAX (0.3)        /* 速度最大値 */
  236.             case 1:/* 回転 */
  237.                 p->round += p->round_v;
  238.                 if ((p->round_v += RA3) > RV3_MAX)
  239.                     p->round_v = RV3_MAX;
  240.                 p->lx = R3 * cos (p->round);
  241.                 p->ly = R3 * sin (p->round);
  242. #define R3_MAX (M_PI)
  243.                 if (p->round > R3_MAX) {
  244.                     p->round -= R3_MAX;
  245.                     p->cyc++;
  246.                 }
  247.                 break;
  248.             case 2:/* ばね振動 */
  249. #define SPRING_K3    0.7
  250. #define SPRING_M3    0.8    /* 摩擦計数 */
  251. #define ROUND_MIN3    0.03    /* 座標がこれ以下になれば中断 */
  252. #define ROUNDV_MIN3    0.03    /* 速度がこれ以下になれば中断 */
  253.                 p->round += p->round_v;
  254.                 p->round_v -= SPRING_K3 * p->round;
  255.                 p->round_v *= SPRING_M3;
  256.                 if ((fabs (p->round) < ROUND_MIN3) && (fabs (p->round_v) < ROUNDV_MIN3))
  257.                     p->cyc++;
  258.                 p->lx = R3 * cos (R3_MAX + p->round);
  259.                 p->ly = R3 * sin (R3_MAX + p->round);
  260.                 break;
  261.             default:
  262.                 break;
  263.             }
  264.             DispSp (p, 42, parts3_table);
  265.             if (seq_counter == SEQ_WING_ERASE)
  266.                 erase_flag = !0;
  267.             break;
  268.  
  269.         case 4:    /* 右翼(大) */
  270.             switch (p->cyc) {
  271.             case 0:
  272.                 p->lx = -R3 * cos (p->round);
  273.                 p->ly = R3 * sin (p->round);
  274.                 if (seq_counter == 25)
  275.                     p->cyc++;
  276.                 break;
  277.             case 1:/* 回転 */
  278.                 p->round += p->round_v;
  279.                 if ((p->round_v += RA3) > RV3_MAX)
  280.                     p->round_v = RV3_MAX;
  281.                 p->lx = -R3 * cos (p->round);
  282.                 p->ly = R3 * sin (p->round);
  283.                 if (p->round > R3_MAX) {
  284.                     p->round -= R3_MAX;
  285.                     p->cyc++;
  286.                 }
  287.                 break;
  288.             case 2:/* ばね振動 */
  289.                 p->round += p->round_v;
  290.                 p->round_v -= SPRING_K3 * p->round;
  291.                 p->round_v *= SPRING_M3;
  292.                 if ((fabs (p->round) < ROUND_MIN3) && (fabs (p->round_v) < ROUNDV_MIN3))
  293.                     p->cyc++;
  294.                 p->lx = -R3 * cos (R3_MAX + p->round);
  295.                 p->ly = R3 * sin (R3_MAX + p->round);
  296.                 break;
  297.             default:
  298.                 break;
  299.             }
  300.             DispSp (p, 42, parts4_table);
  301.             if (seq_counter == SEQ_WING_ERASE)
  302.                 erase_flag = !0;
  303.             break;
  304.  
  305.         case 5:    /* 左耳 */
  306. /* 2段階目左右翼パーツ */
  307. #define P5_K    3.0        /* ばね定数(左右上小パーツ) */
  308. #define P5_M    0.5        /* 摩擦計数(左右上小パーツ) */
  309. #define P5_V    0.7        /* 速度がこれ以下なら次へ(左右上小パーツ) */
  310. #define P5_L    0.7        /* 座標がこれ以下なら次へ(左右上小パーツ) */
  311.             switch (p->cyc) {
  312.             case 0:
  313.                 p->vx -= 0.5;
  314.                 if (p->vx < -3.0)
  315.                     p->vx = -3.0;
  316.                 p->lx += p->vx;
  317.                 if (p->lx < -32.0){
  318.                     p->lx += 32.0;
  319.                     p->ox -= 32;
  320.                     p->cyc++;
  321.                 }
  322.                 break;
  323.             case 1:/* ばね振動 */
  324.                 p->vx -= p->lx * P5_K;
  325.                 /* 摩擦 */
  326.                 if (p->vx > 0)
  327.                     p->vx -= P5_M;
  328.                 else
  329.                     p->vx += P5_M;
  330.                 p->lx += p->vx;
  331.                 if ((fabs (p->vx) < P5_V) && (fabs (p->lx) < P5_L)) {
  332.                     p->cyc++;    /* 次へ */
  333.                     p->lx = 0.0;
  334.                     p->ly = 0.0;
  335.                     p->vx = 0.0;
  336.                     p->vy = 0.0;
  337.                 }
  338.                 break;
  339.             case 2:
  340.                 end_of_data = !0;    /* debug */
  341.                 break;
  342.             default:
  343.                 break;
  344.             }
  345.             if (f_option_flag)
  346.                 fprintf (fp_parts5, "{%d,%d}, ", (int) (p->lx + p->ox), (int) (p->ly + p->oy));
  347.             DispSp (p, 16, parts5_table);
  348.             break;
  349.  
  350.         case 6:    /* 右耳 */
  351.             switch (p->cyc) {
  352.             case 0:
  353.                 p->vx += 0.5;
  354.                 if (p->vx > 3.0)
  355.                     p->vx = 3.0;
  356.                 p->lx += p->vx;
  357.                 if (p->lx > 32.0){
  358.                     p->lx -= 32.0;
  359.                     p->ox += 32;
  360.                     p->cyc++;
  361.                 }
  362.                 break;
  363.             case 1:/* ばね振動 */
  364.                 p->vx -= p->lx * P5_K;
  365.                 /* 摩擦 */
  366.                 if (p->vx > 0)
  367.                     p->vx -= P5_M;
  368.                 else
  369.                     p->vx += P5_M;
  370.                 p->lx += p->vx;
  371.                 if ((fabs (p->vx) < P5_V) && (fabs (p->lx) < P5_L)) {
  372.                     p->cyc++;    /* 次へ */
  373.                     p->lx = 0.0;
  374.                     p->ly = 0.0;
  375.                     p->vx = 0.0;
  376.                     p->vy = 0.0;
  377.                 }
  378.                 break;
  379.             case 2:
  380.                 end_of_data = !0;    /* debug */
  381.                 break;
  382.             default:
  383.                 break;
  384.             }
  385.             if (f_option_flag)
  386.                 fprintf (fp_parts6, "{%d,%d}, ", (int) (p->lx + p->ox), (int) (p->ly + p->oy));
  387.             DispSp (p, 16, parts6_table);
  388.             break;
  389.  
  390.         default:
  391.             printf ("enemy_move() : バグってます\n");
  392.             break;
  393.         }
  394.  
  395.         if (erase_flag) {
  396.             if (q == NULL) {    /* リストの一番最初を削除 */
  397.                 enemy_top = p->next;
  398.                 p->next = enemy_null_top;
  399.                 enemy_null_top = p;
  400.                 q = NULL;
  401.                 p = enemy_top;
  402.             } else {
  403.                 if (p == enemy_end) {    /* リストの一番最後を削除 */
  404.                     q->next = NULL;
  405.                     enemy_end = q;
  406.                     p->next = enemy_null_top;
  407.                     enemy_null_top = p;
  408.                     p = q->next;
  409.                 } else {
  410.                     q->next = p->next;
  411.                     p->next = enemy_null_top;
  412.                     enemy_null_top = p;
  413.                     p = q->next;
  414.                 }
  415.             }
  416.         } else {
  417.             q = p;
  418.             p = p->next;
  419.         }
  420.     }
  421. }
  422.  
  423.  
  424. void EnemyTini (void)
  425. {
  426.     int i;
  427.  
  428.     /* リストをつなげる */
  429.     enemy_top = NULL;
  430.     enemy_null_top = enemy;
  431.     for (i = 0; i < ENEMY_MAX; i++)
  432.         enemy[i].next = &enemy[i + 1];
  433.  
  434.     enemy[ENEMY_MAX - 1].next = NULL;
  435. }
  436.